package cn.wen.mybatis.framework.executor.statement;


import cn.wen.mybatis.framework.executor.Executor;
import cn.wen.mybatis.framework.mapping.BoundSql;
import cn.wen.mybatis.framework.mapping.MappedStatement;
import cn.wen.mybatis.framework.mapping.ResultSetType;
import cn.wen.mybatis.framework.session.ResultHandler;
import cn.wen.mybatis.framework.session.RowBounds;

import java.sql.*;
import java.util.List;

/**
 * PreparedStatement对象处理器,PreparedStatement: 预编译的 SQL 语句的对象
 */
public class PreparedStatementHandler extends BaseStatementHandler {

  public PreparedStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
    super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql);
  }

  @Override
  public int update(Statement statement) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    ps.execute();
    int rows = ps.getUpdateCount();
    return rows;
  }

  @Override
  public void batch(Statement statement) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    ps.addBatch();
  }

  @Override
  public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    // 执行PreparedStatement，也就是执行SQL语句
    ps.execute();
    // 处理结果集
    return resultSetHandler.handleResultSets(ps);
  }


  @Override
  protected Statement instantiateStatement(Connection connection) throws SQLException {
	// 获取带有占位符的SQL语句
    String sql = boundSql.getSql();
    if (mappedStatement.getResultSetType() == ResultSetType.DEFAULT) {
      return connection.prepareStatement(sql);
    } else {
      return connection.prepareStatement(sql, mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY);
    }
  }

  @Override
  public void parameterize(Statement statement) throws SQLException {
	// 通过ParameterHandler处理参数
    parameterHandler.setParameters((PreparedStatement) statement);
  }

}
